#include "gauss_blur.h"

// fixed gaussian kernel (5x5), σ ≈ 1.0
const float gaussian_kernel[5][5] = {
    {1,  4,  7,  4, 1},
    {4, 16, 26, 16, 4},
    {7, 26, 41, 26, 7},
    {4, 16, 26, 16, 4},
    {1,  4,  7,  4, 1}
};
const float gaussian_kernel_sum = 273.0f; // for normalization

// edge handling
int clamp(int val, int min, int max) {
    if (val < min) return min;
    if (val > max) return max;
    return val;
}

void gaussian_blur(unsigned char input[HEIGHT][WIDTH], unsigned char output[HEIGHT][WIDTH]) {
    int ksize = 5;
    int offset = ksize / 2;

    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            float sum = 0.0f;

            for (int ky = -offset; ky <= offset; ky++) {
                for (int kx = -offset; kx <= offset; kx++) {
                    int ix = clamp(x + kx, 0, WIDTH - 1);
                    int iy = clamp(y + ky, 0, HEIGHT - 1);
                    float kernel_val = gaussian_kernel[ky + offset][kx + offset];
                    sum += input[iy][ix] * kernel_val;
                }
            }
            output[y][x] = (unsigned char)(sum / gaussian_kernel_sum);
        }
    }
}
